package com.douqu.game.battle.server.netty;


import com.alibaba.fastjson.JSONObject;
import com.bean.core.buffer.ByteBuffer;
import com.douqu.game.battle.controller.BattleController;
import com.douqu.game.battle.controller.sprite.PlayerController;
import com.douqu.game.battle.server.BattleInitInfo;
import com.douqu.game.battle.server.GameServer;
import com.douqu.game.battle.util.MsgUtils;
import com.douqu.game.core.e.E_BattleEnd;
import com.douqu.game.core.e.E_NoticeType;
import com.douqu.game.core.factory.CodeFactory;
import com.douqu.game.core.factory.ConfigFactory;
import com.douqu.game.core.factory.ConstantFactory;
import com.douqu.game.core.factory.DataFactory;
import com.douqu.game.core.util.*;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import javax.swing.*;
import java.io.File;

/**
 * ChannelInboundHandlerAdapter这个类不会自动释放ByteBuf
 * SimpleChannelInboundHandler这个类会自动释放资源
* Created by Administrator on 2016/11/9.
*/
public class NettyTCPClientHandler extends ChannelInboundHandlerAdapter {


    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception
    {
//        cause.printStackTrace();
        LogUtils.info(cause.getLocalizedMessage());
        ctx.close();
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
    {
        ByteBuf byteBuf = (ByteBuf) msg;
        int code = BufferUtils.readShort(byteBuf);
//        int code = byteBuf.readShortLE();

        LogUtils.info("code:" + code + ",data length:" + byteBuf.readableBytes());

        try{
            if(CodeFactory.GET_BATTLE_SERVER_PORT == code)
            {
                if(!GameServer.getInstance().isRunning())
                {
                    ByteBuffer buffer = CoreUtils.toByteBuffer(byteBuf);
                    int port = buffer.readInt();

                    LogUtils.info("从主服务器获取到TCP端口:"+port);
                    if(port == 0)
                    {
                        JOptionPane.showMessageDialog(null, "没有空闲的战斗服务器端口");
                        System.exit(0);
                    }
                    else
                    {
                        GameServer.getInstance().startBattleTCP(port);

//                        GameServer.getInstance().startRouteServer();

                        GameServer.getInstance().startRMI();

                        GameServer.getInstance().startUpdate();
                    }
                }
            }
            else if(code == CodeFactory.LOAD_DATA)
            {
                DataFactory.getInstance().set(GameServer.getInstance().getIMainServer().getDataFactory());
            }
            else if(code == CodeFactory.SEND_NOTICE)
            {
                ByteBuffer buffer = CoreUtils.toByteBuffer(byteBuf);

                if(buffer.available() > 0)
                {
                    E_NoticeType noticeType = E_NoticeType.getEnum(buffer.readByte());
                    String content = buffer.readUTF();
                    LogUtils.info("公告来了 -> type:" + noticeType.getMsg() + " content:" + content);
                    GameServer.getInstance().getWorldManager().dispatchGM(content,noticeType);
                }
            }
            else if(code == CodeFactory.UPDATE_LOG_CONFIG)
            {
                ByteBuffer buffer = CoreUtils.toByteBuffer(byteBuf);

                if(buffer.available() > 0)
                {
                    String logLevel = buffer.readUTF();
                    boolean battleTimeoutToAI = buffer.readBoolean();
                    LogUtils.info("战斗服收到GM日志设置 -> logLevel:" + logLevel + ", battleTimeoutToAI:" + battleTimeoutToAI);
                    try{
                        ConfigFactory.gmSetting.setBattleTimeoutToAI(battleTimeoutToAI);
                        LogUtils.setLogLevel(LogUtils.LOG_LEVEL.valueOf(logLevel));
                    }catch (Exception e){
                        LogUtils.warn("设置测试配置出错 -> " + logLevel);
                    }
                }
            }
            else if(code == CodeFactory.BATTLE_INIT)
            {
                //接受双方玩家流水号
                ByteBuffer buffer = CoreUtils.toByteBuffer(byteBuf);

                try{
                    JSONObject jsonObject = JSONObject.parseObject(buffer.readUTF());

                    String battleId = jsonObject.getString(CodeFactory.KEY_BATTLE_ID);

                    BattleInitInfo battleInitInfo = GameServer.getInstance().getWorldManager().addBattleInitInfo(jsonObject);

                    if(battleInitInfo.getBattleDetailType().isPlayerBattle())
                    {
                        LogUtils.warn("主服务器发来战斗初始化消息:" + jsonObject);

                        GameServer.getInstance().getIMainServer().battleInit(GameServer.getInstance().getId(), battleId);
                    }
                    else
                    {
                        MsgUtils.createDataBattle(battleInitInfo);
                    }
                }catch (Exception e){
                    e.printStackTrace();
                    LogUtils.error("主服务器发来战斗数据错误:" + buffer.length());
                }
            }
            else if(code == CodeFactory.BATTLE_DATA)
            {
//                ByteBuffer buffer = CoreUtils.toByteBuffer(byteBuf);
//
//                GameServer.getInstance().getWorldManager().sendBattleData(buffer.available() > 0 ? buffer.readUTF() : null);
            }
            else if(code == CodeFactory.PLAYER_OFFLINE)
            {
                LogUtils.warn("主服务器玩家掉线通知战斗服务器 --> ");
                ByteBuffer buffer = CoreUtils.toByteBuffer(byteBuf);

                String battleId = buffer.readUTF();
                BattleController battleController = GameServer.getInstance().getWorldManager().getBattleController(battleId);
                if(battleController != null)
                {
                    String playerIndex = buffer.readUTF();
                    PlayerController playerController = battleController.getPlayerByIndex(playerIndex);
                    if(playerController != null && playerController.getAttachment() != null)
                    {
                        battleController.end(playerController.getAttachment().getTeamNo() == ConstantFactory.BATTLE_TEAM_1 ? ConstantFactory.BATTLE_TEAM_2 : ConstantFactory.BATTLE_TEAM_1, E_BattleEnd.OVERDUE);

                        playerController.sendOffline();
                    }
                }
            }
            else if(code == CodeFactory.UPDATE_CLASS)
            {
                ByteBuffer data = CoreUtils.toByteBuffer(byteBuf);
                String path = data.available() > 0 ? data.readUTF() : HotUpdateUtils.PATH;
                LogUtils.warn("游戏主服务器通知要更新class了 -> " + path);
                File file = HotUpdateUtils.checkDirectory(path);
                if(file == null)
                {
                    LogUtils.error("主服务器通知更新Class的目录不存在或者错误 -> " + path);
                    return;
                }

                GameServer.updating = true;

                HotUpdateUtils.updateClass(file, null);

                GameServer.updating = false;

                LogUtils.warn("更新Class完成---------------------");
            }
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            byteBuf.release();
        }

    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();// 将消息发送队列中的消息写入到SocketChannel中发送给对方。
    }


    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception
    {
        LogUtils.info("客户端连接服务器成功");

        GameServer.getInstance().setServerChannel(ctx.channel());

        SendUtils.sendMsg(ctx.channel(), CodeFactory.GET_BATTLE_SERVER_PORT);
    }


    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception
    {
        LogUtils.info("主服务器已关闭，我也要关服了！");

        GameServer.getInstance().stop();

        ctx.close();

    }




}